#!/usr/bin/env ruby

require 'test/unit'

module DependencyInjection

  IGNORED_SETTERS = ['==', '===']

  # inject dependencies by matching getters on container with setters 
  # on object to recieve injection
  def autowire_dependencies(instance)
    container = self
    instance.methods.each { |setter|
      if setter[-1,1] == '='
        next if IGNORED_SETTERS.include? setter
        getter = setter[0..-2]
        if container.methods.include?(getter)
          instance.send(setter, container.send(getter))
        end
      end
    }
  end  
end

class DependencyInjectionTest < Test::Unit::TestCase

  class Bird
    attr_accessor :wingspan, :air_supply
    def initialize()
      Wildlife.configure(self)
    end
  end
  
  class Wildlife
    include DependencyInjection
    
    attr_reader :air_supply
    
    def initialize()
      @air_supply = 'Oxygen'
    end
    
    def Wildlife.configure(obj)
      @@container ||= Wildlife.new
      @@container.autowire_dependencies(obj)
    end
  end
  
  def setup
    @bird = Bird.new
    @wildlife = Wildlife.new
  end
  
  def test_injection
    assert_equal 'Oxygen', @bird.air_supply
    assert_nil @bird.wingspan
  end
end
